# Import packages
#install.packages("corrplot")
library(dplyr)

Attaching package: <91>dplyr<92>

The following objects are masked from <91>package:stats<92>:

    filter, lag

The following objects are masked from <91>package:base<92>:

    intersect, setdiff, setequal, union
library(data.table)
Registered S3 method overwritten by 'data.table':
  method           from
  print.data.table     
data.table 1.14.6 using 4 threads (see ?getDTthreads).  Latest news: r-datatable.com

Attaching package: <91>data.table<92>

The following objects are masked from <91>package:dplyr<92>:

    between, first, last
library(ggplot2)
library(pastecs)

Attaching package: <91>pastecs<92>

The following objects are masked from <91>package:data.table<92>:

    first, last

The following objects are masked from <91>package:dplyr<92>:

    first, last
library(corrplot)
corrplot 0.92 loaded
#library(ggthemes) # For appearance of plot like theme in ggplot2
# Setting environment
# remove(list=ls())
# setwd("C:\\Users\\sunil\\Downloads\\College\\DAV\\Project")
# make evironment not to change large number to exponential
options(scipen = 999)
# Import dataset
nepal_dt <- read.csv("Source Dataset-API_NPL_DS2.csv", skip=4, header=TRUE, stringsAsFactors = FALSE)
meta_country <- read.csv("MetaData_Country.csv", header=TRUE, stringsAsFactors = FALSE)
meta_indictr <- read.csv("MetaData_Indicator.csv", header=TRUE, stringsAsFactors = FALSE)
nepal_dt
meta_country
meta_indictr

Data Preparation: Preparing data after the import

temp_df = filter(nepal_dt, grepl("tax", tolower(IndicatorName), fixed = TRUE) | grepl("tax", tolower(IndicatorCode), fixed = TRUE))
nepal_df <- temp_df
nepal_df
dim(nepal_df)
[1] 53 66
temp_df = filter(nepal_dt, grepl("gdp", tolower(IndicatorName), fixed = TRUE) | grepl("gdp", tolower(IndicatorCode), fixed = TRUE))
nepal_df <- rbind(nepal_df, temp_df)
nepal_df
dim(nepal_df)
[1] 143  66
temp_df = filter(nepal_dt, grepl("employment", tolower(IndicatorName), fixed = TRUE) | grepl("employment", tolower(IndicatorCode), fixed = TRUE))
nepal_df <- rbind(nepal_df, temp_df)
nepal_df
# Drop first and second column
nepal_df <- nepal_df[-c(1,2)]
nepal_df
# unique(nepal_df$IndicatorName)
#table(tolower(nepal_df$IndicatorName))
# Transposing the dataframe
# df_t <- (t(nepal_df))
df_t <- transpose(nepal_df)
rownames(df_t) <- colnames(nepal_df)
colnames(df_t) <- rownames(nepal_df)
#View(df_t)
df_t[0,]
# Rename the columns with the first row. Columns are not properly renamed from above lines.
colnames(df_t) <- df_t[2,]
# Remove the first and second row.
df_t <- df_t[-1:-2,]
nepal_df <- df_t
View(nepal_df)
# Keep rownames as a first column
#setDT(df_t, keep.rownames = TRUE)[]
nepal_df <- cbind(names = rownames(nepal_df), nepal_df)
colnames(nepal_df)[1] <- "YEAR"
# Removing a character 'X' from the column: YEAR in nepal_df
nepal_df$YEAR <- gsub("X","",as.character(nepal_df$YEAR))
nepal_df
dim(nepal_df)[2]
[1] 243
nepal_df
# Converting columns to numeric types
#nepal_df$TM.TAX.MRCH.WM.AR.ZS = as.numeric(as.character(nepal_df$TM.TAX.MRCH.WM.AR.ZS))
#nepal_df$NY.GDP.PETR.RT.ZS = as.numeric(as.character(nepal_df$NY.GDP.PETR.RT.ZS))
nepal_df[1:dim(nepal_df)[2]] <- sapply(nepal_df[1:dim(nepal_df)[2]],as.numeric)
sapply(nepal_df, class)
                    YEAR     TM.TAX.MRCH.WM.AR.ZS        TM.TAX.MRCH.IP.ZS           NY.TAX.NIND.KN 
               "numeric"                "numeric"                "numeric"                "numeric" 
       TM.TAX.TCOM.BC.ZS        TM.TAX.MANF.BC.ZS        GC.TAX.INTT.RV.ZS     TM.TAX.MRCH.WM.FN.ZS 
               "numeric"                "numeric"                "numeric"                "numeric" 
    TM.TAX.MRCH.SM.AR.ZS        TM.TAX.TCOM.IP.ZS        TM.TAX.MANF.IP.ZS           IC.TAX.GIFT.ZS 
               "numeric"                "numeric"                "numeric"                "numeric" 
       GC.TAX.TOTL.GD.ZS        GC.TAX.GSRV.VA.ZS        IC.TAX.LABR.CP.ZS           GC.TAX.YPKG.CN 
               "numeric"                "numeric"                "numeric"                "numeric" 
       TM.TAX.MRCH.BR.ZS           NY.TAX.NIND.CN        TM.TAX.MRCH.SR.ZS        IC.TAX.OTHR.CP.ZS 
               "numeric"                "numeric"                "numeric"                "numeric" 
          GC.TAX.YPKG.ZS           GC.TAX.IMPT.ZS           GC.TAX.OTHR.CN           GC.TAX.IMPT.CN 
               "numeric"                "numeric"                "numeric"                "numeric" 
    TM.TAX.TCOM.WM.AR.ZS     TM.TAX.MANF.WM.AR.ZS              IC.TAX.PAYM           GC.TAX.EXPT.CN 
               "numeric"                "numeric"                "numeric"                "numeric" 
       IC.TAX.TOTL.CP.ZS           IC.FRM.INFM.ZS           GC.TAX.GSRV.CN           GC.TAX.INTT.CN 
               "numeric"                "numeric"                "numeric"                "numeric" 
    TM.TAX.TCOM.WM.FN.ZS     TM.TAX.MANF.WM.FN.ZS     TM.TAX.MRCH.SM.FN.ZS     TM.TAX.TCOM.SM.AR.ZS 
               "numeric"                "numeric"                "numeric"                "numeric" 
    TM.TAX.MANF.SM.AR.ZS           IC.FRM.METG.ZS        GC.TAX.GSRV.RV.ZS        TM.TAX.MRCH.BC.ZS 
               "numeric"                "numeric"                "numeric"                "numeric" 
          NY.TAX.NIND.CD     TM.TAX.TCOM.SM.FN.ZS     TM.TAX.MANF.SM.FN.ZS              IC.TAX.METG 
               "numeric"                "numeric"                "numeric"                "numeric" 
       GC.TAX.YPKG.RV.ZS              IC.TAX.DURS           GC.TAX.TOTL.CN        TM.TAX.TCOM.BR.ZS 
               "numeric"                "numeric"                "numeric"                "numeric" 
       TM.TAX.MANF.BR.ZS        TM.TAX.TCOM.SR.ZS        TM.TAX.MANF.SR.ZS        IC.TAX.PRFT.CP.ZS 
               "numeric"                "numeric"                "numeric"                "numeric" 
          GC.TAX.EXPT.ZS        GC.TAX.OTHR.RV.ZS        TG.VAL.TOTL.GD.ZS           NY.GDP.MKTP.KD 
               "numeric"                "numeric"                "numeric"                "numeric" 
       NY.GDP.COAL.RT.ZS        NY.GDP.PCAP.PP.KD        NY.GDP.MINR.RT.ZS           NY.GDP.MKTP.KN 
               "numeric"                "numeric"                "numeric"                "numeric" 
    NY.GDP.DEFL.KD.ZG.AD           NV.SRV.TOTL.ZS        ER.GDP.FWTL.M3.KD     BX.TRF.PWKR.DT.GD.ZS 
               "numeric"                "numeric"                "numeric"                "numeric" 
       SL.GDP.PCAP.EM.KD        SE.XPD.TERT.PC.ZS           NY.GDS.TOTL.ZS        NY.GDP.MKTP.KD.ZG 
               "numeric"                "numeric"                "numeric"                "numeric" 
       NY.GDP.DEFL.KD.ZG        SH.XPD.CHEX.GD.ZS        SE.XPD.PRIM.PC.ZS        NY.GDP.PETR.RT.ZS 
               "numeric"                "numeric"                "numeric"                "numeric" 
          NY.GDP.MKTP.CD           NE.DAB.TOTL.ZS        SH.XPD.GHED.GD.ZS        SE.XPD.TOTL.GD.ZS 
               "numeric"                "numeric"                "numeric"                "numeric" 
          PA.NUS.PPPC.RF        NY.GDP.MKTP.PP.KD        NY.GDP.DEFL.ZS.AD           NE.GDI.TOTL.ZS 
               "numeric"                "numeric"                "numeric"                "numeric" 
       GC.TAX.TOTL.GD.ZS        FS.AST.DOMS.GD.ZS        FM.AST.PRVT.GD.ZS        EN.ATM.CO2E.KD.GD 
               "numeric"                "numeric"                "numeric"                "numeric" 
       NY.GDP.PCAP.PP.CD        NY.GDP.FRST.RT.ZS           NE.GDI.FTOT.ZS        SE.XPD.SECO.PC.ZS 
               "numeric"                "numeric"                "numeric"                "numeric" 
       NY.GDP.MKTP.CN.AD           NV.IND.MANF.ZS           NE.TRD.GNFS.ZS        GC.REV.XGRT.GD.ZS 
               "numeric"                "numeric"                "numeric"                "numeric" 
       GB.XPD.RSDV.GD.ZS     EG.USE.COMM.GD.PP.KD        GC.NLD.TOTL.GD.ZS        BN.CAB.XOKA.GD.ZS 
               "numeric"                "numeric"                "numeric"                "numeric" 
       BG.GSR.NFSV.GD.ZS           NE.CON.PRVT.ZS        GC.LBL.TOTL.GD.ZS        FS.AST.PRVT.GD.ZS 
               "numeric"                "numeric"                "numeric"                "numeric" 
    BM.KLT.DINV.WD.GD.ZS           NY.GDP.PCAP.KD           NY.GDP.FCST.CN        FS.AST.CGOV.GD.ZS 
               "numeric"                "numeric"                "numeric"                "numeric" 
       EN.ATM.CO2E.PP.GD     EG.GDP.PUSE.KO.PP.KD        EG.EGY.PRIM.PP.KD        GC.NFN.TOTL.GD.ZS 
               "numeric"                "numeric"                "numeric"                "numeric" 
       FM.LBL.BMNY.GD.ZS        NY.GDP.PCAP.KD.ZG           NY.GDP.FCST.KD        NY.GDP.TOTL.RT.ZS 
               "numeric"                "numeric"                "numeric"                "numeric" 
          NY.GDP.MKTP.CN           NE.RSB.GNFS.ZS        MS.MIL.XPND.GD.ZS        NY.GDP.NGAS.RT.ZS 
               "numeric"                "numeric"                "numeric"                "numeric" 
          NY.GDP.DISC.CN           NV.IND.TOTL.ZS           NE.GDI.FPRV.ZS        GC.DOD.TOTL.GD.ZS 
               "numeric"                "numeric"                "numeric"                "numeric" 
       FS.AST.DOMO.GD.ZS     EN.ATM.CO2E.PP.GD.KD     BX.KLT.DINV.WD.GD.ZS           NY.GDP.PCAP.KN 
               "numeric"                "numeric"                "numeric"                "numeric" 
          NY.GDP.FCST.KN           NE.IMP.GNFS.ZS           NY.GNS.ICTR.ZS           NY.GDP.PCAP.CD 
               "numeric"                "numeric"                "numeric"                "numeric" 
          NY.GDP.DISC.KN           NV.AGR.TOTL.ZS        CM.MKT.TRAD.GD.ZS        CM.MKT.LCAP.GD.ZS 
               "numeric"                "numeric"                "numeric"                "numeric" 
              PA.NUS.PPP        NY.GDP.MKTP.PP.CD           NY.GDP.DEFL.ZS           NE.EXP.GNFS.ZS 
               "numeric"                "numeric"                "numeric"                "numeric" 
          NY.GDP.PCAP.CN           NY.GDP.FCST.CD           NE.CON.TOTL.ZS        GC.AST.TOTL.GD.ZS 
               "numeric"                "numeric"                "numeric"                "numeric" 
       EG.GDP.PUSE.KO.PP           NE.CON.GOVT.ZS        GC.XPN.TOTL.GD.ZS        FD.AST.PRVT.GD.ZS 
               "numeric"                "numeric"                "numeric"                "numeric" 
          SL.UEM.NEET.ZS        SL.UEM.1524.FE.ZS           SL.SRV.EMPL.ZS           SL.FAM.WORK.ZS 
               "numeric"                "numeric"                "numeric"                "numeric" 
    SL.EMP.TOTL.SP.FE.ZS        SL.AGR.EMPL.MA.ZS  per_lm_alllm.cov_q5_tot        SL.UEM.INTM.MA.ZS 
               "numeric"                "numeric"                "numeric"                "numeric" 
          SL.TLF.PART.ZS     SL.TLF.0714.WK.MA.ZS        SL.SRV.0714.MA.ZS        SL.FAM.0714.MA.ZS 
               "numeric"                "numeric"                "numeric"                "numeric" 
       SL.EMP.SELF.MA.ZS        SL.AGR.0714.FE.ZS  per_lm_alllm.cov_q1_tot        SL.UEM.TOTL.FE.ZS 
               "numeric"                "numeric"                "numeric"                "numeric" 
       SL.UEM.1524.MA.ZS        SL.TLF.0714.MA.ZS        SL.IND.EMPL.FE.ZS     SL.EMP.TOTL.SP.MA.ZS 
               "numeric"                "numeric"                "numeric"                "numeric" 
 SL.EMP.1524.SP.FE.NE.ZS     SL.UEM.TOTL.FE.NE.ZS     SL.UEM.1524.MA.NE.ZS        SL.TLF.0714.FE.ZS 
               "numeric"                "numeric"                "numeric"                "numeric" 
 SL.EMP.TOTL.SP.MA.NE.ZS           SL.AGR.EMPL.ZS           SL.UEM.INTM.ZS           SL.SRV.0714.ZS 
               "numeric"                "numeric"                "numeric"                "numeric" 
          SL.FAM.0714.ZS           SL.EMP.SELF.ZS        SL.AGR.0714.MA.ZS  per_lm_alllm.cov_q2_tot 
               "numeric"                "numeric"                "numeric"                "numeric" 
       SL.UEM.TOTL.MA.ZS           SL.UEM.1524.ZS     SL.TLF.0714.SW.FE.ZS           SL.IND.EMPL.ZS 
               "numeric"                "numeric"                "numeric"                "numeric" 
       SL.EMP.TOTL.SP.ZS  SL.EMP.1524.SP.MA.NE.ZS        SL.UEM.INTM.FE.ZS        SL.TLF.PART.MA.ZS 
               "numeric"                "numeric"                "numeric"                "numeric" 
       SL.SRV.0714.FE.ZS        SL.FAM.0714.FE.ZS        SL.EMP.SELF.FE.ZS per_lm_alllm.cov_pop_tot 
               "numeric"                "numeric"                "numeric"                "numeric" 
       SL.UEM.NEET.MA.ZS     SL.UEM.1524.FE.NE.ZS           SL.TLF.0714.ZS        SL.SRV.EMPL.MA.ZS 
               "numeric"                "numeric"                "numeric"                "numeric" 
       SL.FAM.WORK.MA.ZS  SL.EMP.TOTL.SP.FE.NE.ZS        SL.AGR.EMPL.FE.ZS  per_lm_alllm.cov_q4_tot 
               "numeric"                "numeric"                "numeric"                "numeric" 
       SL.WAG.0714.MA.ZS        SL.UEM.BASC.FE.ZS        SL.TLF.0714.SW.ZS        SL.SLF.0714.FE.ZS 
               "numeric"                "numeric"                "numeric"                "numeric" 
       SL.EMP.WORK.FE.ZS        SL.EMP.MPYR.FE.ZS           SL.WAG.0714.ZS        SL.UEM.BASC.MA.ZS 
               "numeric"                "numeric"                "numeric"                "numeric" 
       SL.SLF.0714.MA.ZS        SL.EMP.WORK.MA.ZS        SL.EMP.MPYR.MA.ZS per_lm_alllm.adq_pop_tot 
               "numeric"                "numeric"                "numeric"                "numeric" 
       SL.UEM.NEET.FE.ZS        SL.TLF.0714.WK.ZS        SL.SRV.EMPL.FE.ZS        SL.FAM.WORK.FE.ZS 
               "numeric"                "numeric"                "numeric"                "numeric" 
       SL.EMP.SMGT.FE.ZS           SL.AGR.0714.ZS  per_lm_alllm.cov_q3_tot        SL.UEM.TOTL.NE.ZS 
               "numeric"                "numeric"                "numeric"                "numeric" 
       SL.UEM.ADVN.FE.ZS        SL.MNF.0714.FE.ZS        SL.EMP.VULN.FE.ZS     SL.EMP.1524.SP.MA.ZS 
               "numeric"                "numeric"                "numeric"                "numeric" 
          SL.UEM.BASC.ZS        SL.TLF.PART.FE.ZS     SL.TLF.0714.WK.FE.ZS           SL.SLF.0714.ZS 
               "numeric"                "numeric"                "numeric"                "numeric" 
          SL.EMP.WORK.ZS           SL.EMP.MPYR.ZS  per_lm_alllm.ben_q1_tot           SL.UEM.TOTL.ZS 
               "numeric"                "numeric"                "numeric"                "numeric" 
       SL.UEM.ADVN.MA.ZS     SL.TLF.0714.SW.MA.ZS        SL.MNF.0714.MA.ZS        SL.EMP.VULN.MA.ZS 
               "numeric"                "numeric"                "numeric"                "numeric" 
    SL.EMP.1524.SP.NE.ZS     SL.UEM.TOTL.MA.NE.ZS        SL.UEM.1524.NE.ZS        SL.IND.EMPL.MA.ZS 
               "numeric"                "numeric"                "numeric"                "numeric" 
    SL.EMP.TOTL.SP.NE.ZS     SL.EMP.1524.SP.FE.ZS        SL.WAG.0714.FE.ZS           SL.UEM.ADVN.ZS 
               "numeric"                "numeric"                "numeric"                "numeric" 
          SL.MNF.0714.ZS           SL.EMP.VULN.ZS        SL.EMP.1524.SP.ZS 
               "numeric"                "numeric"                "numeric" 
# Replace NA values with 0
#nepal_df["TM.TAX.MRCH.WM.AR.ZS"][is.na(nepal_df["TM.TAX.MRCH.WM.AR.ZS"])] <- 0
#nepal_df["NY.GDP.PETR.RT.ZS"][is.na(nepal_df["NY.GDP.PETR.RT.ZS"])] <- 0
# Replace na values with 0 using is.na()
nepal_df[is.na(nepal_df)] <- 0
nepal_df
# Viewing the data after preparing it.
View(nepal_df)

Parameter Selection:

## Sample parameters selection to achieve project objective.
# GC.TAX.GSRV.VA.ZS -> Taxes on goods and services(%)
# GC.TAX.GSRV.CN -> Taxes on goods and services (current LCU)
# GC.TAX.TOTL.GD.ZS -> Tax revenue (% of GDP)
# IC.TAX.LABR.CP.ZS -> Labor tax and contributions (% of commercial profits) | Labor tax and contributions is the amount of taxes and mandatory contributions on labor paid by the business.
# GC.TAX.YPKG.CN -> Taxes on income, profits and capital gains (current LCU)
# GC.TAX.IMPT.ZS -> Customs and other import duties (% of tax revenue)
# GC.TAX.IMPT.CN -> Customs and other import duties (current LCU)
# GC.TAX.EXPT.ZS -> Taxes on exports (% of tax revenue)
# GC.TAX.EXPT.CN -> Taxes on exports (current LCU)
# IC.TAX.TOTL.CP.ZS -> Total tax and contribution rate (% of profit)
# NY.GDP.MKTP.KD -> GDP (constant 2015 US$)
# NY.GDP.MKTP.KD.ZG -> GDP growth (annual %)
# SL.IND.EMPL.ZS -> Employment in industry (% of total employment) (modeled ILO estimate)
# SL.IND.EMPL.FE.ZS -> Employment in industry, female (% of female employment) (modeled ILO estimate)
# SL.IND.EMPL.MA.ZS -> Employment in industry, male (% of male employment) (modeled ILO estimate)
# SL.AGR.EMPL.ZS -> Employment in agriculture (% of total employment) (modeled ILO estimate)
# SL.AGR.EMPL.FE.ZS -> Employment in agriculture, female (% of female employment) (modeled ILO estimate)
# SL.AGR.EMPL.MA.ZS -> Employment in agriculture, male (% of male employment) (modeled ILO estimate)
## Sample parameter selection to achieve project objective.
# GC.TAX.GSRV.VA.ZS, NY.GDP.MKTP.KD  0.8481471
# GC.TAX.GSRV.VA.ZS, SL.IND.EMPL.ZS  0.8880489
# GC.TAX.GSRV.VA.ZS, SL.IND.EMPL.FE.ZS 0.8928028
# GC.TAX.GSRV.VA.ZS, SL.IND.EMPL.MA.ZS 0.8939309
# GC.TAX.GSRV.VA.ZS, SL.AGR.EMPL.ZS 0.8268747
# GC.TAX.GSRV.VA.ZS, SL.AGR.EMPL.FE.ZS 0.8333567
# GC.TAX.GSRV.VA.ZS, SL.AGR.EMPL.MA.ZS 0.8062022
# GC.TAX.INTT.RV.ZS, SL.IND.EMPL.ZS 0.727295
# GC.TAX.INTT.RV.ZS, SL.IND.EMPL.FE.ZS 0.7059692
# GC.TAX.INTT.RV.ZS, SL.IND.EMPL.MA.ZS 0.7179946
# GC.TAX.TOTL.GD.ZS, SL.IND.EMPL.ZS 0.893035
# GC.TAX.TOTL.GD.ZS, SL.IND.EMPL.FE.ZS 0.8984195
# GC.TAX.TOTL.GD.ZS, SL.IND.EMPL.MA.ZS 0.8992892
# IC.TAX.LABR.CP.ZS
# GC.TAX.YPKG.CN
# GC.TAX.IMPT.ZS
# GC.TAX.EXPT.CN
# IC.TAX.TOTL.CP.ZS
## Sample parameters selection to achieve project objective.
nepal_df <- select(nepal_df, 'YEAR', 'GC.TAX.GSRV.VA.ZS', 'GC.TAX.GSRV.CN', 'GC.TAX.TOTL.GD.ZS', 'IC.TAX.LABR.CP.ZS', 'GC.TAX.YPKG.CN', 'GC.TAX.IMPT.ZS', 'GC.TAX.IMPT.CN', 'GC.TAX.EXPT.ZS', 'GC.TAX.EXPT.CN', 'IC.TAX.TOTL.CP.ZS', 'NY.GDP.MKTP.KD', 'NY.GDP.MKTP.KD.ZG', 'SL.IND.EMPL.ZS', 'SL.IND.EMPL.FE.ZS', 'SL.IND.EMPL.MA.ZS', 'SL.AGR.EMPL.ZS', 'SL.AGR.EMPL.FE.ZS', 'SL.AGR.EMPL.MA.ZS')
nepal_df

Data Quality: Checking the data

## Checking quality of data in parameters selected.
#View(truncate(summary(nepal_df)))
#df_t <- summary(nepal_df)
#View(t(df_t))
View(summary(nepal_df))
stat.desc(nepal_df)

Correlation Analysis: Exploring relationship between employment, tax and GDP. Understanding what drives economic activity.

# Finding correlation between each columns in the dataframe
# cor(nepal_df$TM.TAX.MRCH.WM.AR.ZS, nepal_df$NY.GDP.PETR.RT.ZS)
# cor(nepal_df$GC.TAX.TOTL.GD.ZS, nepal_df$SL.IND.EMPL.FE.ZS)
View(cor(nepal_df))
# Correlation matrix plot
corrplot(cor(nepal_df), type="lower")

var(nepal_df$GC.TAX.GSRV.VA.ZS)
[1] 26.21113
# SL.IND.EMPL.ZS  NY.GDP.MKTP.KD

Time series analysis: Trends/patterns in the data over time

# autoregressive integrated moving average (ARIMA) - need to look at it
# GDP = Consumption + Investment + Government spending + Net exports
p <- ggplot(nepal_df, aes(x=nepal_df$YEAR, y=nepal_df$GC.TAX.GSRV.VA.ZS)) +
  geom_line( color="steelblue") + 
  geom_point() +
  xlab("YEAR") +
  ylab("Taxes on goods and services(%)") +
  ggtitle("Percent increase on tax on goods & services each year")
  #scale_x_date(limit=c(as.Date("1960-01-01"),as.Date("2022-12-30"))) +
  
p

  1. The percent increase in tax on goods and services have remained around 5.5% from year 1990 to 2005.
  2. The percent increase in tax on goods and services has been increasing after the year 2005.
# Check tax and gdp over time
coeff <- 10
tax_color <- "black"
gdp_color <- "steelblue"
ggplot(nepal_df, aes(x=nepal_df$YEAR)) +
  
  geom_line( aes(y=nepal_df$GC.TAX.GSRV.CN), size=0.5, color=tax_color) + 
  geom_line( aes(y=nepal_df$NY.GDP.MKTP.KD), size=0.5, color=gdp_color) +
  
  geom_point(aes(y = nepal_df$GC.TAX.GSRV.CN), size=2, color=tax_color) +
  geom_point(aes(y = nepal_df$NY.GDP.MKTP.KD), size=2, color=gdp_color) +
  
  scale_y_continuous(
    
    # First axis
    name = "Taxes on goods and services (current LCU)",
    
    # Second axis
    sec.axis = sec_axis(~.*1, name="GDP (constant 2015 US$)")
  ) +
#  theme_ipsum() +
  scale_x_continuous(
    name = "YEAR"
  ) +
  theme(
    axis.title.y = element_text(color = tax_color, size=13),
    axis.title.y.right = element_text(color = gdp_color, size=13)
  ) +
  ggtitle("Tax and GDP over time") +
  theme(plot.title = element_text(hjust = 0.5)) #Title to be at center
Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.

  1. As the tax on goods and services have increased after the year 2005, the GDP has remained same.
  2. Though the correlation between the indicator (GC.TAX.GSRV.CN & NY.GDP.MKTP.KD) is , the tax has no impact on the GDP growth over the years.
# Check employment in industry and agriculture over the years.
coeff <- 10
ind_color <- "black"
agr_color <- "steelblue"
ggplot(nepal_df, aes(x=nepal_df$YEAR)) +
  
  geom_line( aes(y=nepal_df$SL.IND.EMPL.ZS), size=0.5, color=ind_color) + 
  geom_line( aes(y=nepal_df$SL.AGR.EMPL.ZS), size=0.5, color=agr_color) +
  
  geom_point(aes(y = nepal_df$SL.IND.EMPL.ZS), size=2, color=ind_color) +
  geom_point(aes(y = nepal_df$SL.AGR.EMPL.ZS), size=2, color=agr_color) +
  
  scale_y_continuous(
    
    # First axis
    name = "Employment in industry (% of total employment)",
    
    # Second axis
    sec.axis = sec_axis(~.*1, name="Employment in agriculture (% of total employment)")
  ) +
#  theme_ipsum() +
  scale_x_continuous(
    name = "YEAR"
  ) +
  theme(
    axis.title.y = element_text(color = ind_color, size=13),
    axis.title.y.right = element_text(color = agr_color, size=13)
  ) +
  ggtitle("Employment in industry & agriculture over time") +
  theme(plot.title = element_text(hjust = 0.5)) #Title to be at center

  1. After the year 1990, employment in the industrial sector has been increasing each year by .
  2. After the year 1990, employment in the agriculture sector has been decreasing each year by .
coeff <- 10
ind_color <- "black"
agr_color <- "steelblue"
ggplot(nepal_df, aes(x=nepal_df$YEAR)) +
  
  geom_line( aes(y=nepal_df$SL.IND.EMPL.FE.ZS), size=0.5, color=ind_color) + 
  geom_line( aes(y=nepal_df$SL.AGR.EMPL.FE.ZS), size=0.5, color=agr_color) +
  
  geom_point(aes(y = nepal_df$SL.IND.EMPL.FE.ZS), size=2, color=ind_color) +
  geom_point(aes(y = nepal_df$SL.AGR.EMPL.FE.ZS), size=2, color=agr_color) +
  
  scale_y_continuous(
    
    # First axis
    name = "Employment in industry, female (% of female employment)",
    
    # Second axis
    sec.axis = sec_axis(~.*1, name="Employment in agriculture, female (% of female employment)")
  ) +
#  theme_ipsum() +
  scale_x_continuous(
    name = "YEAR"
  ) +
  theme(
    axis.title.y = element_text(color = ind_color, size=13),
    axis.title.y.right = element_text(color = agr_color, size=13)
  ) +
  ggtitle("Employment in industry & agriculture, females over time") +
  theme(plot.title = element_text(hjust = 0.5)) #Title to be at center

  1. Percentage in female employment in industry has been increasing by .
  2. Percentage in female employment in agricuture has been decreasing by .
coeff <- 10
ind_color <- "black"
agr_color <- "steelblue"
ggplot(nepal_df, aes(x=nepal_df$YEAR)) +
  
  geom_line( aes(y=nepal_df$SL.IND.EMPL.MA.ZS), size=0.5, color=ind_color) + 
  geom_line( aes(y=nepal_df$SL.AGR.EMPL.MA.ZS), size=0.5, color=agr_color) +
  
  geom_point(aes(y = nepal_df$SL.IND.EMPL.MA.ZS), size=2, color=ind_color) +
  geom_point(aes(y = nepal_df$SL.AGR.EMPL.MA.ZS), size=2, color=agr_color) +
  
  scale_y_continuous(
    
    # First axis
    name = "Employment in industry, male (% of male employment)",
    
    # Second axis
    sec.axis = sec_axis(~.*1, name="Employment in agriculture, male (% of male employment)")
  ) +
#  theme_ipsum() +
  scale_x_continuous(
    name = "YEAR"
  ) +
  theme(
    axis.title.y = element_text(color = ind_color, size=13),
    axis.title.y.right = element_text(color = agr_color, size=13)
  ) +
  ggtitle("Employment in industry & agriculture, males over time") +
  theme(plot.title = element_text(hjust = 0.5)) #Title to be at center

  1. Percentage in male employment in industry has been increasing by .
  2. Percentage in male employment in agriculture has been decreasing by .

Regression:

#help(“scale_x_continuous”)

ggplot(nepal_df, aes(x = GC.TAX.GSRV.CN, y = NY.GDP.MKTP.KD)) +
  geom_point() +
geom_smooth() + 
# Add a regression line
xlab("Taxes on goods and services (current LCU)") +
ylab("GDP (constant 2015 US$)") +
scale_x_continuous() +
scale_y_continuous() +
ggtitle("Regression: GDP x taxes on goods & services")

  1. As taxes on goods and services increases, the GDP has been increasing.
  2. The correlation between the two indicators () as , says the same.
# Checking GDP growth on every tax % increase
# with trend line (regression line)
ggplot(nepal_df, aes(x = GC.TAX.GSRV.VA.ZS, y = NY.GDP.MKTP.KD)) +
  geom_point() +
geom_smooth() + # Add a regression line
xlab("Taxes on goods and services (% value added of industry and services)") +
ylab("GDP (constant 2015 US$)") +
scale_x_continuous() +
scale_y_continuous() +
ggtitle("Regression: GDP x taxes on goods & services")

  1. Taxes on goods and services above 10% shows increase in GDP.
  2. When taxes on goods and services are within the range 6.5% to 8.5%, the GDP has been fluctuating.
# Check employment in industry on every tax % increase
# with trend line (regression line)
ggplot(nepal_df, aes(x = SL.IND.EMPL.ZS, y = GC.TAX.GSRV.VA.ZS)) +
  geom_point() +
geom_smooth() + # Add a regression line
xlab("Employment in industry (% of total employment)") +
ylab("Taxes on goods and services (% value added of industry and services)") +
scale_x_continuous() +
scale_y_continuous() +
ggtitle("Regression: Tax on goods & services X Employment in industry")

  1. Increase in taxes on goods and services above 7% shows increase in percent of employment in industry.
  2. Likewise, the taxes around 7.5% shows percent of employment in industry from 2.5% to 10%.
# Check employment in agriculture on every tax % increase
# with trend line (regression line)
ggplot(nepal_df, aes(x = GC.TAX.GSRV.VA.ZS, y = SL.AGR.EMPL.ZS )) +
  geom_point() +
geom_smooth() + # Add a regression line
xlab("Taxes on goods and services (% value added of industry and services)") +
ylab("Employment in agriculture (% of total employment)") +
scale_x_continuous() +
scale_y_continuous() +
ggtitle("Regression: Tax on goods & services X Employment in agriculture")

  1. Despite the correlation between the indicators (), the increase in taxes on goods and services shows slow decrease in employment in agriculture.
# Check employment in industry on every customs/import duties % increase
# with trend line (regression line)
ggplot(nepal_df, aes(x = GC.TAX.IMPT.ZS, y = SL.IND.EMPL.ZS)) +
  geom_point() +
geom_smooth() + # Add a regression line
xlab("Customs and other import duties (% of tax revenue)") +
ylab("Employment in industry (% of total employment)") +
scale_x_continuous() +
scale_y_continuous() +
ggtitle("Regression: Customs Import duties X Employment in industry")

  1. As customs and import duties increases, the employment in industrial sector decreases.
  2. It can be concluded that as customs and import duties is above 25%, we can see steep decline in employment in industry.
# Check employment in agriculture on every customs/import duties % increase
# with trend line (regression line)
ggplot(nepal_df, aes(x = GC.TAX.IMPT.ZS, y = SL.AGR.EMPL.ZS)) +
  geom_point() +
geom_smooth() + # Add a regression line
xlab("Customs and other import duties (% of tax revenue)") +
ylab("Employment in agriculture (% of total employment)") +
scale_x_continuous() +
scale_y_continuous() +
ggtitle("Regression: Customs Import duties X Employment in agriculture")

  1. Though the correlation between the two indicator ( and ) is , the increase in customs and import duties has small change on the employment in agriculture.
# Check employment in industry on every export taxes % increase
# with trend line (regression line)
ggplot(nepal_df, aes(x = GC.TAX.EXPT.ZS , y = SL.IND.EMPL.ZS )) +
  geom_point() +
geom_smooth() + # Add a regression line
xlab("Taxes on exports (% of tax revenue)") +
ylab("Employment in industry (% of total employment)") +
scale_x_continuous() +
scale_y_continuous() +
ggtitle("Regression: Exports taxes vs Employment in Industry")

  1. As taxes on exports increases, the employment in industry remains unchanged(but slightly decreasing).
# Check employment in industry on every export taxes % increase
# with trend line (regression line)
ggplot(nepal_df, aes(x = GC.TAX.EXPT.ZS, y = SL.AGR.EMPL.ZS)) +
  geom_point() +
geom_smooth() + # Add a regression line
xlab("Taxes on exports (% of tax revenue)") +
ylab("Employment in agriculture (% of total employment)") +
scale_x_continuous() +
scale_y_continuous() +
ggtitle("Regression: Exports vs Employment in Agriculture")

  1. As taxes on exports increases, the employment in agriculture remains unchanged(but slightly increasing).

Bar Plots:

# Check employment in agriculture on every export taxes % increase
# with trend line (regression line)
ggplot(nepal_df, aes(x = nepal_df$SL.IND.EMPL.ZS, y = nepal_df$NY.GDP.MKTP.KD, fill = nepal_df$SL.IND.EMPL.ZS)) +
  geom_bar(stat = "identity", position = "dodge", width = 0.08) +
  #theme_bw() +
  xlab("Employment in industry (% of total employment)") +
  ylab("GDP (constant 2015 US$)") +
  theme(axis.text.x = element_text(size = 10)) +
  theme(axis.text.y = element_text(size = 10)) +
  ggtitle("Bar plot: GDP vs Employment in industry")

  1. GDP is highest(around $30 billion) when employment in industry(% of total employment) is 15%.
  2. GDP is lowest(below $10 billion) when employment in industry(% of total employment) is 2.7%.
ggplot(nepal_df, aes(x = nepal_df$GC.TAX.GSRV.VA.ZS, y = nepal_df$NY.GDP.MKTP.KD, fill = nepal_df$GC.TAX.GSRV.VA.ZS)) +
  geom_bar(stat = "identity", position = "dodge", width = 0.08) +
  #theme_bw() +
  xlab("Taxes on goods and services(%)") +
  ylab("GDP (constant 2015 US$)") +
  theme(axis.text.x = element_text(size = 10)) +
  theme(axis.text.y = element_text(size = 10)) +
  ggtitle("Bar plot: GDP vs Taxes on goods & services(%)")

#GC.TAX.GSRV.VA.ZS, NY.GDP.MKTP.KD
  1. GDP is highest(around $30 billion) when employment in taxes on goods and sevices is 10.6%.
  2. GDP is lowest(below $10 billion) when employment in industry(% of total employment) is 7%.

Cluster Analysis:

# Scatterplot for Taxes on goods and services and GDP
There were 15 warnings (use warnings() to see them)
library(scatterplot3d)
scatterplot3d(nepal_df$GC.TAX.GSRV.CN, nepal_df$NY.GDP.MKTP.KD, nepal_df$SL.IND.EMPL.ZS,
              xlab = "Tax", ylab = "GDP", zlab = "Employment",
              type = "h", main = "3D Scatterplot")

#library(rgl)
#plot3d(nepal_df$GC.TAX.GSRV.CN, nepal_df$NY.GDP.MKTP.KD, nepal_df$SL.IND.EMPL.ZS)

Add a new chunk by clicking the Insert Chunk button on the toolbar or by pressing Ctrl+Alt+I.

When you save the notebook, an HTML file containing the code and output will be saved alongside it (click the Preview button or press Ctrl+Shift+K to preview the HTML file).

The preview shows you a rendered HTML copy of the contents of the editor. Consequently, unlike Knit, Preview does not run any R code chunks. Instead, the output of the chunk when it was last run in the editor is displayed.

This is an R Markdown Notebook. When you execute code within the notebook, the results appear beneath the code.

Try executing this chunk by clicking the Run button within the chunk or by placing your cursor inside it and pressing Ctrl+Shift+Enter.

LS0tDQp0aXRsZTogIkFuYWx5emluZyBlY29ub21pYyB0cmVuZHMgaW4gTmVwYWwiDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQoNCmBgYHtyfQ0KIyBJbXBvcnQgcGFja2FnZXMNCg0KI2luc3RhbGwucGFja2FnZXMoImNvcnJwbG90IikNCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KGRhdGEudGFibGUpDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KHBhc3RlY3MpDQpsaWJyYXJ5KGNvcnJwbG90KQ0KI2xpYnJhcnkoZ2d0aGVtZXMpICMgRm9yIGFwcGVhcmFuY2Ugb2YgcGxvdCBsaWtlIHRoZW1lIGluIGdncGxvdDINCmBgYA0KDQpgYGB7cn0NCiMgU2V0dGluZyBlbnZpcm9ubWVudA0KIyByZW1vdmUobGlzdD1scygpKQ0KIyBzZXR3ZCgiQzpcXFVzZXJzXFxzdW5pbFxcRG93bmxvYWRzXFxDb2xsZWdlXFxEQVZcXFByb2plY3QiKQ0KIyBtYWtlIGV2aXJvbm1lbnQgbm90IHRvIGNoYW5nZSBsYXJnZSBudW1iZXIgdG8gZXhwb25lbnRpYWwNCm9wdGlvbnMoc2NpcGVuID0gOTk5KQ0KYGBgDQoNCmBgYHtyfQ0KIyBJbXBvcnQgZGF0YXNldA0KbmVwYWxfZHQgPC0gcmVhZC5jc3YoIlNvdXJjZSBEYXRhc2V0LUFQSV9OUExfRFMyLmNzdiIsIHNraXA9NCwgaGVhZGVyPVRSVUUsIHN0cmluZ3NBc0ZhY3RvcnMgPSBGQUxTRSkNCm1ldGFfY291bnRyeSA8LSByZWFkLmNzdigiTWV0YURhdGFfQ291bnRyeS5jc3YiLCBoZWFkZXI9VFJVRSwgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFKQ0KbWV0YV9pbmRpY3RyIDwtIHJlYWQuY3N2KCJNZXRhRGF0YV9JbmRpY2F0b3IuY3N2IiwgaGVhZGVyPVRSVUUsIHN0cmluZ3NBc0ZhY3RvcnMgPSBGQUxTRSkNCm5lcGFsX2R0DQptZXRhX2NvdW50cnkNCm1ldGFfaW5kaWN0cg0KYGBgDQoNCg0KRGF0YSBQcmVwYXJhdGlvbjogUHJlcGFyaW5nIGRhdGEgYWZ0ZXIgdGhlIGltcG9ydA0KDQpgYGB7cn0NCnRlbXBfZGYgPSBmaWx0ZXIobmVwYWxfZHQsIGdyZXBsKCJ0YXgiLCB0b2xvd2VyKEluZGljYXRvck5hbWUpLCBmaXhlZCA9IFRSVUUpIHwgZ3JlcGwoInRheCIsIHRvbG93ZXIoSW5kaWNhdG9yQ29kZSksIGZpeGVkID0gVFJVRSkpDQpuZXBhbF9kZiA8LSB0ZW1wX2RmDQpuZXBhbF9kZg0KYGBgDQoNCmBgYHtyfQ0KZGltKG5lcGFsX2RmKQ0KYGBgDQoNCmBgYHtyfQ0KdGVtcF9kZiA9IGZpbHRlcihuZXBhbF9kdCwgZ3JlcGwoImdkcCIsIHRvbG93ZXIoSW5kaWNhdG9yTmFtZSksIGZpeGVkID0gVFJVRSkgfCBncmVwbCgiZ2RwIiwgdG9sb3dlcihJbmRpY2F0b3JDb2RlKSwgZml4ZWQgPSBUUlVFKSkNCm5lcGFsX2RmIDwtIHJiaW5kKG5lcGFsX2RmLCB0ZW1wX2RmKQ0KbmVwYWxfZGYNCmBgYA0KDQpgYGB7cn0NCmRpbShuZXBhbF9kZikNCmBgYA0KDQpgYGB7cn0NCnRlbXBfZGYgPSBmaWx0ZXIobmVwYWxfZHQsIGdyZXBsKCJlbXBsb3ltZW50IiwgdG9sb3dlcihJbmRpY2F0b3JOYW1lKSwgZml4ZWQgPSBUUlVFKSB8IGdyZXBsKCJlbXBsb3ltZW50IiwgdG9sb3dlcihJbmRpY2F0b3JDb2RlKSwgZml4ZWQgPSBUUlVFKSkNCm5lcGFsX2RmIDwtIHJiaW5kKG5lcGFsX2RmLCB0ZW1wX2RmKQ0KbmVwYWxfZGYNCmBgYA0KDQpgYGB7cn0NCiMgRHJvcCBmaXJzdCBhbmQgc2Vjb25kIGNvbHVtbg0KDQpuZXBhbF9kZiA8LSBuZXBhbF9kZlstYygxLDIpXQ0KbmVwYWxfZGYNCmBgYA0KDQpgYGB7cn0NCiMgdW5pcXVlKG5lcGFsX2RmJEluZGljYXRvck5hbWUpDQojdGFibGUodG9sb3dlcihuZXBhbF9kZiRJbmRpY2F0b3JOYW1lKSkNCmBgYA0KDQpgYGB7cn0NCiMgVHJhbnNwb3NpbmcgdGhlIGRhdGFmcmFtZQ0KDQojIGRmX3QgPC0gKHQobmVwYWxfZGYpKQ0KDQpkZl90IDwtIHRyYW5zcG9zZShuZXBhbF9kZikNCnJvd25hbWVzKGRmX3QpIDwtIGNvbG5hbWVzKG5lcGFsX2RmKQ0KY29sbmFtZXMoZGZfdCkgPC0gcm93bmFtZXMobmVwYWxfZGYpDQojVmlldyhkZl90KQ0KYGBgDQoNCmBgYHtyfQ0KZGZfdFswLF0NCmBgYA0KDQpgYGB7cn0NCiMgUmVuYW1lIHRoZSBjb2x1bW5zIHdpdGggdGhlIGZpcnN0IHJvdy4gQ29sdW1ucyBhcmUgbm90IHByb3Blcmx5IHJlbmFtZWQgZnJvbSBhYm92ZSBsaW5lcy4NCmNvbG5hbWVzKGRmX3QpIDwtIGRmX3RbMixdDQoNCiMgUmVtb3ZlIHRoZSBmaXJzdCBhbmQgc2Vjb25kIHJvdy4NCmRmX3QgPC0gZGZfdFstMTotMixdDQpuZXBhbF9kZiA8LSBkZl90DQpWaWV3KG5lcGFsX2RmKQ0KYGBgDQoNCmBgYHtyfQ0KIyBLZWVwIHJvd25hbWVzIGFzIGEgZmlyc3QgY29sdW1uDQoNCiNzZXREVChkZl90LCBrZWVwLnJvd25hbWVzID0gVFJVRSlbXQ0KbmVwYWxfZGYgPC0gY2JpbmQobmFtZXMgPSByb3duYW1lcyhuZXBhbF9kZiksIG5lcGFsX2RmKQ0KY29sbmFtZXMobmVwYWxfZGYpWzFdIDwtICJZRUFSIg0KDQojIFJlbW92aW5nIGEgY2hhcmFjdGVyICdYJyBmcm9tIHRoZSBjb2x1bW46IFlFQVIgaW4gbmVwYWxfZGYNCm5lcGFsX2RmJFlFQVIgPC0gZ3N1YigiWCIsIiIsYXMuY2hhcmFjdGVyKG5lcGFsX2RmJFlFQVIpKQ0KbmVwYWxfZGYNCmBgYA0KDQpgYGB7cn0NCmRpbShuZXBhbF9kZilbMl0NCmBgYA0KDQpgYGB7cn0NCm5lcGFsX2RmDQpgYGANCg0KYGBge3J9DQojIENvbnZlcnRpbmcgY29sdW1ucyB0byBudW1lcmljIHR5cGVzDQoNCiNuZXBhbF9kZiRUTS5UQVguTVJDSC5XTS5BUi5aUyA9IGFzLm51bWVyaWMoYXMuY2hhcmFjdGVyKG5lcGFsX2RmJFRNLlRBWC5NUkNILldNLkFSLlpTKSkNCiNuZXBhbF9kZiROWS5HRFAuUEVUUi5SVC5aUyA9IGFzLm51bWVyaWMoYXMuY2hhcmFjdGVyKG5lcGFsX2RmJE5ZLkdEUC5QRVRSLlJULlpTKSkNCg0KbmVwYWxfZGZbMTpkaW0obmVwYWxfZGYpWzJdXSA8LSBzYXBwbHkobmVwYWxfZGZbMTpkaW0obmVwYWxfZGYpWzJdXSxhcy5udW1lcmljKQ0Kc2FwcGx5KG5lcGFsX2RmLCBjbGFzcykNCmBgYA0KDQpgYGB7cn0NCiMgUmVwbGFjZSBOQSB2YWx1ZXMgd2l0aCAwDQojbmVwYWxfZGZbIlRNLlRBWC5NUkNILldNLkFSLlpTIl1baXMubmEobmVwYWxfZGZbIlRNLlRBWC5NUkNILldNLkFSLlpTIl0pXSA8LSAwDQojbmVwYWxfZGZbIk5ZLkdEUC5QRVRSLlJULlpTIl1baXMubmEobmVwYWxfZGZbIk5ZLkdEUC5QRVRSLlJULlpTIl0pXSA8LSAwDQoNCiMgUmVwbGFjZSBuYSB2YWx1ZXMgd2l0aCAwIHVzaW5nIGlzLm5hKCkNCm5lcGFsX2RmW2lzLm5hKG5lcGFsX2RmKV0gPC0gMA0KYGBgDQoNCmBgYHtyfQ0KbmVwYWxfZGYNCmBgYA0KDQpgYGB7cn0NCiMgVmlld2luZyB0aGUgZGF0YSBhZnRlciBwcmVwYXJpbmcgaXQuDQpWaWV3KG5lcGFsX2RmKQ0KYGBgDQoNCg0KUGFyYW1ldGVyIFNlbGVjdGlvbjogDQoNCmBgYHtyfQ0KIyMgU2FtcGxlIHBhcmFtZXRlcnMgc2VsZWN0aW9uIHRvIGFjaGlldmUgcHJvamVjdCBvYmplY3RpdmUuDQojIEdDLlRBWC5HU1JWLlZBLlpTIC0+IFRheGVzIG9uIGdvb2RzIGFuZCBzZXJ2aWNlcyglKQ0KIyBHQy5UQVguR1NSVi5DTiAtPiBUYXhlcyBvbiBnb29kcyBhbmQgc2VydmljZXMgKGN1cnJlbnQgTENVKQ0KIyBHQy5UQVguVE9UTC5HRC5aUyAtPiBUYXggcmV2ZW51ZSAoJSBvZiBHRFApDQojIElDLlRBWC5MQUJSLkNQLlpTIC0+IExhYm9yIHRheCBhbmQgY29udHJpYnV0aW9ucyAoJSBvZiBjb21tZXJjaWFsIHByb2ZpdHMpIHwgTGFib3IgdGF4IGFuZCBjb250cmlidXRpb25zIGlzIHRoZSBhbW91bnQgb2YgdGF4ZXMgYW5kIG1hbmRhdG9yeSBjb250cmlidXRpb25zIG9uIGxhYm9yIHBhaWQgYnkgdGhlIGJ1c2luZXNzLg0KIyBHQy5UQVguWVBLRy5DTiAtPiBUYXhlcyBvbiBpbmNvbWUsIHByb2ZpdHMgYW5kIGNhcGl0YWwgZ2FpbnMgKGN1cnJlbnQgTENVKQ0KIyBHQy5UQVguSU1QVC5aUyAtPglDdXN0b21zIGFuZCBvdGhlciBpbXBvcnQgZHV0aWVzICglIG9mIHRheCByZXZlbnVlKQ0KIyBHQy5UQVguSU1QVC5DTiAtPiBDdXN0b21zIGFuZCBvdGhlciBpbXBvcnQgZHV0aWVzIChjdXJyZW50IExDVSkNCiMgR0MuVEFYLkVYUFQuWlMgLT4JVGF4ZXMgb24gZXhwb3J0cyAoJSBvZiB0YXggcmV2ZW51ZSkNCiMgR0MuVEFYLkVYUFQuQ04gLT4gVGF4ZXMgb24gZXhwb3J0cyAoY3VycmVudCBMQ1UpDQojIElDLlRBWC5UT1RMLkNQLlpTIC0+IFRvdGFsIHRheCBhbmQgY29udHJpYnV0aW9uIHJhdGUgKCUgb2YgcHJvZml0KQ0KDQojIE5ZLkdEUC5NS1RQLktEIC0+IEdEUCAoY29uc3RhbnQgMjAxNSBVUyQpDQojIE5ZLkdEUC5NS1RQLktELlpHCS0+IEdEUCBncm93dGggKGFubnVhbCAlKQ0KDQojIFNMLklORC5FTVBMLlpTIC0+CUVtcGxveW1lbnQgaW4gaW5kdXN0cnkgKCUgb2YgdG90YWwgZW1wbG95bWVudCkgKG1vZGVsZWQgSUxPIGVzdGltYXRlKQ0KIyBTTC5JTkQuRU1QTC5GRS5aUyAtPiBFbXBsb3ltZW50IGluIGluZHVzdHJ5LCBmZW1hbGUgKCUgb2YgZmVtYWxlIGVtcGxveW1lbnQpIChtb2RlbGVkIElMTyBlc3RpbWF0ZSkNCiMgU0wuSU5ELkVNUEwuTUEuWlMgLT4gRW1wbG95bWVudCBpbiBpbmR1c3RyeSwgbWFsZSAoJSBvZiBtYWxlIGVtcGxveW1lbnQpIChtb2RlbGVkIElMTyBlc3RpbWF0ZSkNCiMgU0wuQUdSLkVNUEwuWlMgLT4gRW1wbG95bWVudCBpbiBhZ3JpY3VsdHVyZSAoJSBvZiB0b3RhbCBlbXBsb3ltZW50KSAobW9kZWxlZCBJTE8gZXN0aW1hdGUpDQojIFNMLkFHUi5FTVBMLkZFLlpTIC0+IEVtcGxveW1lbnQgaW4gYWdyaWN1bHR1cmUsIGZlbWFsZSAoJSBvZiBmZW1hbGUgZW1wbG95bWVudCkgKG1vZGVsZWQgSUxPIGVzdGltYXRlKQ0KIyBTTC5BR1IuRU1QTC5NQS5aUyAtPiBFbXBsb3ltZW50IGluIGFncmljdWx0dXJlLCBtYWxlICglIG9mIG1hbGUgZW1wbG95bWVudCkgKG1vZGVsZWQgSUxPIGVzdGltYXRlKQ0KYGBgDQoNCmBgYHtyfQ0KIyMgU2FtcGxlIHBhcmFtZXRlciBzZWxlY3Rpb24gdG8gYWNoaWV2ZSBwcm9qZWN0IG9iamVjdGl2ZS4NCiMgR0MuVEFYLkdTUlYuVkEuWlMsIE5ZLkdEUC5NS1RQLktEICAwLjg0ODE0NzENCiMgR0MuVEFYLkdTUlYuVkEuWlMsIFNMLklORC5FTVBMLlpTICAwLjg4ODA0ODkNCiMgR0MuVEFYLkdTUlYuVkEuWlMsIFNMLklORC5FTVBMLkZFLlpTIDAuODkyODAyOA0KIyBHQy5UQVguR1NSVi5WQS5aUywgU0wuSU5ELkVNUEwuTUEuWlMgMC44OTM5MzA5DQojIEdDLlRBWC5HU1JWLlZBLlpTLCBTTC5BR1IuRU1QTC5aUyAwLjgyNjg3NDcNCiMgR0MuVEFYLkdTUlYuVkEuWlMsIFNMLkFHUi5FTVBMLkZFLlpTIDAuODMzMzU2Nw0KIyBHQy5UQVguR1NSVi5WQS5aUywgU0wuQUdSLkVNUEwuTUEuWlMgMC44MDYyMDIyDQojIEdDLlRBWC5JTlRULlJWLlpTLCBTTC5JTkQuRU1QTC5aUyAwLjcyNzI5NQ0KIyBHQy5UQVguSU5UVC5SVi5aUywgU0wuSU5ELkVNUEwuRkUuWlMgMC43MDU5NjkyDQojIEdDLlRBWC5JTlRULlJWLlpTLCBTTC5JTkQuRU1QTC5NQS5aUyAwLjcxNzk5NDYNCiMgR0MuVEFYLlRPVEwuR0QuWlMsIFNMLklORC5FTVBMLlpTIDAuODkzMDM1DQojIEdDLlRBWC5UT1RMLkdELlpTLCBTTC5JTkQuRU1QTC5GRS5aUyAwLjg5ODQxOTUNCiMgR0MuVEFYLlRPVEwuR0QuWlMsIFNMLklORC5FTVBMLk1BLlpTIDAuODk5Mjg5Mg0KIyBJQy5UQVguTEFCUi5DUC5aUw0KIyBHQy5UQVguWVBLRy5DTg0KIyBHQy5UQVguSU1QVC5aUw0KIyBHQy5UQVguRVhQVC5DTg0KIyBJQy5UQVguVE9UTC5DUC5aUw0KDQpgYGANCg0KYGBge3J9DQojIyBTYW1wbGUgcGFyYW1ldGVycyBzZWxlY3Rpb24gdG8gYWNoaWV2ZSBwcm9qZWN0IG9iamVjdGl2ZS4NCm5lcGFsX2RmIDwtIHNlbGVjdChuZXBhbF9kZiwgJ1lFQVInLCAnR0MuVEFYLkdTUlYuVkEuWlMnLCAnR0MuVEFYLkdTUlYuQ04nLCAnR0MuVEFYLlRPVEwuR0QuWlMnLCAnSUMuVEFYLkxBQlIuQ1AuWlMnLCAnR0MuVEFYLllQS0cuQ04nLCAnR0MuVEFYLklNUFQuWlMnLCAnR0MuVEFYLklNUFQuQ04nLCAnR0MuVEFYLkVYUFQuWlMnLCAnR0MuVEFYLkVYUFQuQ04nLCAnSUMuVEFYLlRPVEwuQ1AuWlMnLCAnTlkuR0RQLk1LVFAuS0QnLCAnTlkuR0RQLk1LVFAuS0QuWkcnLCAnU0wuSU5ELkVNUEwuWlMnLCAnU0wuSU5ELkVNUEwuRkUuWlMnLCAnU0wuSU5ELkVNUEwuTUEuWlMnLCAnU0wuQUdSLkVNUEwuWlMnLCAnU0wuQUdSLkVNUEwuRkUuWlMnLCAnU0wuQUdSLkVNUEwuTUEuWlMnKQ0KbmVwYWxfZGYNCmBgYA0KDQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KDQoNCkRhdGEgUXVhbGl0eTogQ2hlY2tpbmcgdGhlIGRhdGEgDQoNCmBgYHtyfQ0KIyMgQ2hlY2tpbmcgcXVhbGl0eSBvZiBkYXRhIGluIHBhcmFtZXRlcnMgc2VsZWN0ZWQuDQojVmlldyh0cnVuY2F0ZShzdW1tYXJ5KG5lcGFsX2RmKSkpDQojZGZfdCA8LSBzdW1tYXJ5KG5lcGFsX2RmKQ0KI1ZpZXcodChkZl90KSkNClZpZXcoc3VtbWFyeShuZXBhbF9kZikpDQpgYGANCg0KYGBge3J9DQpzdGF0LmRlc2MobmVwYWxfZGYpDQpgYGANCg0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCg0KDQpDb3JyZWxhdGlvbiBBbmFseXNpczogRXhwbG9yaW5nIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIGVtcGxveW1lbnQsIHRheCBhbmQgR0RQLiBVbmRlcnN0YW5kaW5nIHdoYXQgZHJpdmVzIGVjb25vbWljIGFjdGl2aXR5Lg0KDQpgYGB7cn0NCiMgRmluZGluZyBjb3JyZWxhdGlvbiBiZXR3ZWVuIGVhY2ggY29sdW1ucyBpbiB0aGUgZGF0YWZyYW1lDQoNCiMgY29yKG5lcGFsX2RmJFRNLlRBWC5NUkNILldNLkFSLlpTLCBuZXBhbF9kZiROWS5HRFAuUEVUUi5SVC5aUykNCiMgY29yKG5lcGFsX2RmJEdDLlRBWC5UT1RMLkdELlpTLCBuZXBhbF9kZiRTTC5JTkQuRU1QTC5GRS5aUykNCg0KVmlldyhjb3IobmVwYWxfZGYpKQ0KYGBgDQoNCmBgYHtyfQ0KIyBDb3JyZWxhdGlvbiBtYXRyaXggcGxvdA0KDQpjb3JycGxvdChjb3IobmVwYWxfZGYpLCB0eXBlPSJsb3dlciIpDQpgYGANCg0KYGBge3J9DQp2YXIobmVwYWxfZGYkR0MuVEFYLkdTUlYuVkEuWlMpDQojIFNMLklORC5FTVBMLlpTICBOWS5HRFAuTUtUUC5LRA0KYGBgDQoNCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCg0KVGltZSBzZXJpZXMgYW5hbHlzaXM6IFRyZW5kcy9wYXR0ZXJucyBpbiB0aGUgZGF0YSBvdmVyIHRpbWUNCg0KYGBge3IgZmlnLmhlaWdodCA9IDQsIGZpZy53aWR0aCA9IDExfQ0KIyBhdXRvcmVncmVzc2l2ZSBpbnRlZ3JhdGVkIG1vdmluZyBhdmVyYWdlIChBUklNQSkgLSBuZWVkIHRvIGxvb2sgYXQgaXQNCiMgR0RQID0gQ29uc3VtcHRpb24gKyBJbnZlc3RtZW50ICsgR292ZXJubWVudCBzcGVuZGluZyArIE5ldCBleHBvcnRzDQoNCnAgPC0gZ2dwbG90KG5lcGFsX2RmLCBhZXMoeD1uZXBhbF9kZiRZRUFSLCB5PW5lcGFsX2RmJEdDLlRBWC5HU1JWLlZBLlpTKSkgKw0KICBnZW9tX2xpbmUoIGNvbG9yPSJzdGVlbGJsdWUiKSArIA0KICBnZW9tX3BvaW50KCkgKw0KICB4bGFiKCJZRUFSIikgKw0KICB5bGFiKCJUYXhlcyBvbiBnb29kcyBhbmQgc2VydmljZXMoJSkiKSArDQogIGdndGl0bGUoIlBlcmNlbnQgaW5jcmVhc2Ugb24gdGF4IG9uIGdvb2RzICYgc2VydmljZXMgZWFjaCB5ZWFyIikNCiAgI3NjYWxlX3hfZGF0ZShsaW1pdD1jKGFzLkRhdGUoIjE5NjAtMDEtMDEiKSxhcy5EYXRlKCIyMDIyLTEyLTMwIikpKSArDQogIA0KcA0KYGBgDQogIDEuIFRoZSBwZXJjZW50IGluY3JlYXNlIGluIHRheCBvbiBnb29kcyBhbmQgc2VydmljZXMgaGF2ZSByZW1haW5lZCBhcm91bmQgNS41JSBmcm9tIHllYXIgMTk5MCB0byAyMDA1Lg0KICAyLiBUaGUgcGVyY2VudCBpbmNyZWFzZSBpbiB0YXggb24gZ29vZHMgYW5kIHNlcnZpY2VzIGhhcyBiZWVuIGluY3JlYXNpbmcgYWZ0ZXIgdGhlIHllYXIgMjAwNS4NCiAgDQoNCmBgYHtyIGZpZy5oZWlnaHQgPSA2LCBmaWcud2lkdGggPSAxNH0NCg0KIyBDaGVjayB0YXggYW5kIGdkcCBvdmVyIHRpbWUNCg0KY29lZmYgPC0gMTANCnRheF9jb2xvciA8LSAiYmxhY2siDQpnZHBfY29sb3IgPC0gInN0ZWVsYmx1ZSINCg0KZ2dwbG90KG5lcGFsX2RmLCBhZXMoeD1uZXBhbF9kZiRZRUFSKSkgKw0KICANCiAgZ2VvbV9saW5lKCBhZXMoeT1uZXBhbF9kZiRHQy5UQVguR1NSVi5DTiksIHNpemU9MC41LCBjb2xvcj10YXhfY29sb3IpICsgDQogIGdlb21fbGluZSggYWVzKHk9bmVwYWxfZGYkTlkuR0RQLk1LVFAuS0QpLCBzaXplPTAuNSwgY29sb3I9Z2RwX2NvbG9yKSArDQogIA0KICBnZW9tX3BvaW50KGFlcyh5ID0gbmVwYWxfZGYkR0MuVEFYLkdTUlYuQ04pLCBzaXplPTIsIGNvbG9yPXRheF9jb2xvcikgKw0KICBnZW9tX3BvaW50KGFlcyh5ID0gbmVwYWxfZGYkTlkuR0RQLk1LVFAuS0QpLCBzaXplPTIsIGNvbG9yPWdkcF9jb2xvcikgKw0KICANCiAgc2NhbGVfeV9jb250aW51b3VzKA0KICAgIA0KICAgICMgRmlyc3QgYXhpcw0KICAgIG5hbWUgPSAiVGF4ZXMgb24gZ29vZHMgYW5kIHNlcnZpY2VzIChjdXJyZW50IExDVSkiLA0KICAgIA0KICAgICMgU2Vjb25kIGF4aXMNCiAgICBzZWMuYXhpcyA9IHNlY19heGlzKH4uKjEsIG5hbWU9IkdEUCAoY29uc3RhbnQgMjAxNSBVUyQpIikNCiAgKSArDQoNCiMgIHRoZW1lX2lwc3VtKCkgKw0KICBzY2FsZV94X2NvbnRpbnVvdXMoDQogICAgbmFtZSA9ICJZRUFSIg0KICApICsNCg0KICB0aGVtZSgNCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoY29sb3IgPSB0YXhfY29sb3IsIHNpemU9MTMpLA0KICAgIGF4aXMudGl0bGUueS5yaWdodCA9IGVsZW1lbnRfdGV4dChjb2xvciA9IGdkcF9jb2xvciwgc2l6ZT0xMykNCiAgKSArDQoNCiAgZ2d0aXRsZSgiVGF4IGFuZCBHRFAgb3ZlciB0aW1lIikgKw0KICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSkgI1RpdGxlIHRvIGJlIGF0IGNlbnRlcg0KDQpgYGANCiAgMS4gQXMgdGhlIHRheCBvbiBnb29kcyBhbmQgc2VydmljZXMgaGF2ZSBpbmNyZWFzZWQgYWZ0ZXIgdGhlIHllYXIgMjAwNSwgdGhlIEdEUCBoYXMgcmVtYWluZWQgc2FtZS4NCiAgMi4gVGhvdWdoIHRoZSBjb3JyZWxhdGlvbiBiZXR3ZWVuIHRoZSBpbmRpY2F0b3IgKEdDLlRBWC5HU1JWLkNOICYgTlkuR0RQLk1LVFAuS0QpIGlzICwgdGhlIHRheCBoYXMgbm8gaW1wYWN0IG9uIHRoZSAgICAgICAgR0RQIGdyb3d0aCBvdmVyIHRoZSB5ZWFycy4NCiAgDQogIA0KYGBge3J9DQojIENoZWNrIGVtcGxveW1lbnQgaW4gaW5kdXN0cnkgYW5kIGFncmljdWx0dXJlIG92ZXIgdGhlIHllYXJzLg0KDQpjb2VmZiA8LSAxMA0KaW5kX2NvbG9yIDwtICJibGFjayINCmFncl9jb2xvciA8LSAic3RlZWxibHVlIg0KDQpnZ3Bsb3QobmVwYWxfZGYsIGFlcyh4PW5lcGFsX2RmJFlFQVIpKSArDQogIA0KICBnZW9tX2xpbmUoIGFlcyh5PW5lcGFsX2RmJFNMLklORC5FTVBMLlpTKSwgc2l6ZT0wLjUsIGNvbG9yPWluZF9jb2xvcikgKyANCiAgZ2VvbV9saW5lKCBhZXMoeT1uZXBhbF9kZiRTTC5BR1IuRU1QTC5aUyksIHNpemU9MC41LCBjb2xvcj1hZ3JfY29sb3IpICsNCiAgDQogIGdlb21fcG9pbnQoYWVzKHkgPSBuZXBhbF9kZiRTTC5JTkQuRU1QTC5aUyksIHNpemU9MiwgY29sb3I9aW5kX2NvbG9yKSArDQogIGdlb21fcG9pbnQoYWVzKHkgPSBuZXBhbF9kZiRTTC5BR1IuRU1QTC5aUyksIHNpemU9MiwgY29sb3I9YWdyX2NvbG9yKSArDQogIA0KICBzY2FsZV95X2NvbnRpbnVvdXMoDQogICAgDQogICAgIyBGaXJzdCBheGlzDQogICAgbmFtZSA9ICJFbXBsb3ltZW50IGluIGluZHVzdHJ5ICglIG9mIHRvdGFsIGVtcGxveW1lbnQpIiwNCiAgICANCiAgICAjIFNlY29uZCBheGlzDQogICAgc2VjLmF4aXMgPSBzZWNfYXhpcyh+LioxLCBuYW1lPSJFbXBsb3ltZW50IGluIGFncmljdWx0dXJlICglIG9mIHRvdGFsIGVtcGxveW1lbnQpIikNCiAgKSArDQoNCiMgIHRoZW1lX2lwc3VtKCkgKw0KICBzY2FsZV94X2NvbnRpbnVvdXMoDQogICAgbmFtZSA9ICJZRUFSIg0KICApICsNCg0KICB0aGVtZSgNCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoY29sb3IgPSBpbmRfY29sb3IsIHNpemU9MTMpLA0KICAgIGF4aXMudGl0bGUueS5yaWdodCA9IGVsZW1lbnRfdGV4dChjb2xvciA9IGFncl9jb2xvciwgc2l6ZT0xMykNCiAgKSArDQoNCiAgZ2d0aXRsZSgiRW1wbG95bWVudCBpbiBpbmR1c3RyeSAmIGFncmljdWx0dXJlIG92ZXIgdGltZSIpICsNCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkpICNUaXRsZSB0byBiZSBhdCBjZW50ZXINCg0KYGBgDQogIDEuIEFmdGVyIHRoZSB5ZWFyIDE5OTAsIGVtcGxveW1lbnQgaW4gdGhlIGluZHVzdHJpYWwgc2VjdG9yIGhhcyBiZWVuIGluY3JlYXNpbmcgZWFjaCB5ZWFyIGJ5IC4NCiAgMi4gQWZ0ZXIgdGhlIHllYXIgMTk5MCwgZW1wbG95bWVudCBpbiB0aGUgYWdyaWN1bHR1cmUgc2VjdG9yIGhhcyBiZWVuIGRlY3JlYXNpbmcgZWFjaCB5ZWFyIGJ5IC4NCiAgDQogIA0KYGBge3J9DQpjb2VmZiA8LSAxMA0KaW5kX2NvbG9yIDwtICJibGFjayINCmFncl9jb2xvciA8LSAic3RlZWxibHVlIg0KDQpnZ3Bsb3QobmVwYWxfZGYsIGFlcyh4PW5lcGFsX2RmJFlFQVIpKSArDQogIA0KICBnZW9tX2xpbmUoIGFlcyh5PW5lcGFsX2RmJFNMLklORC5FTVBMLkZFLlpTKSwgc2l6ZT0wLjUsIGNvbG9yPWluZF9jb2xvcikgKyANCiAgZ2VvbV9saW5lKCBhZXMoeT1uZXBhbF9kZiRTTC5BR1IuRU1QTC5GRS5aUyksIHNpemU9MC41LCBjb2xvcj1hZ3JfY29sb3IpICsNCiAgDQogIGdlb21fcG9pbnQoYWVzKHkgPSBuZXBhbF9kZiRTTC5JTkQuRU1QTC5GRS5aUyksIHNpemU9MiwgY29sb3I9aW5kX2NvbG9yKSArDQogIGdlb21fcG9pbnQoYWVzKHkgPSBuZXBhbF9kZiRTTC5BR1IuRU1QTC5GRS5aUyksIHNpemU9MiwgY29sb3I9YWdyX2NvbG9yKSArDQogIA0KICBzY2FsZV95X2NvbnRpbnVvdXMoDQogICAgDQogICAgIyBGaXJzdCBheGlzDQogICAgbmFtZSA9ICJFbXBsb3ltZW50IGluIGluZHVzdHJ5LCBmZW1hbGUgKCUgb2YgZmVtYWxlIGVtcGxveW1lbnQpIiwNCiAgICANCiAgICAjIFNlY29uZCBheGlzDQogICAgc2VjLmF4aXMgPSBzZWNfYXhpcyh+LioxLCBuYW1lPSJFbXBsb3ltZW50IGluIGFncmljdWx0dXJlLCBmZW1hbGUgKCUgb2YgZmVtYWxlIGVtcGxveW1lbnQpIikNCiAgKSArDQoNCiMgIHRoZW1lX2lwc3VtKCkgKw0KICBzY2FsZV94X2NvbnRpbnVvdXMoDQogICAgbmFtZSA9ICJZRUFSIg0KICApICsNCg0KICB0aGVtZSgNCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoY29sb3IgPSBpbmRfY29sb3IsIHNpemU9MTMpLA0KICAgIGF4aXMudGl0bGUueS5yaWdodCA9IGVsZW1lbnRfdGV4dChjb2xvciA9IGFncl9jb2xvciwgc2l6ZT0xMykNCiAgKSArDQoNCiAgZ2d0aXRsZSgiRW1wbG95bWVudCBpbiBpbmR1c3RyeSAmIGFncmljdWx0dXJlLCBmZW1hbGVzIG92ZXIgdGltZSIpICsNCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkpICNUaXRsZSB0byBiZSBhdCBjZW50ZXINCmBgYA0KICAxLiBQZXJjZW50YWdlIGluIGZlbWFsZSBlbXBsb3ltZW50IGluIGluZHVzdHJ5IGhhcyBiZWVuIGluY3JlYXNpbmcgYnkgLg0KICAyLiBQZXJjZW50YWdlIGluIGZlbWFsZSBlbXBsb3ltZW50IGluIGFncmljdXR1cmUgaGFzIGJlZW4gZGVjcmVhc2luZyBieSAuDQogIA0KICANCmBgYHtyfQ0KY29lZmYgPC0gMTANCmluZF9jb2xvciA8LSAiYmxhY2siDQphZ3JfY29sb3IgPC0gInN0ZWVsYmx1ZSINCg0KZ2dwbG90KG5lcGFsX2RmLCBhZXMoeD1uZXBhbF9kZiRZRUFSKSkgKw0KICANCiAgZ2VvbV9saW5lKCBhZXMoeT1uZXBhbF9kZiRTTC5JTkQuRU1QTC5NQS5aUyksIHNpemU9MC41LCBjb2xvcj1pbmRfY29sb3IpICsgDQogIGdlb21fbGluZSggYWVzKHk9bmVwYWxfZGYkU0wuQUdSLkVNUEwuTUEuWlMpLCBzaXplPTAuNSwgY29sb3I9YWdyX2NvbG9yKSArDQogIA0KICBnZW9tX3BvaW50KGFlcyh5ID0gbmVwYWxfZGYkU0wuSU5ELkVNUEwuTUEuWlMpLCBzaXplPTIsIGNvbG9yPWluZF9jb2xvcikgKw0KICBnZW9tX3BvaW50KGFlcyh5ID0gbmVwYWxfZGYkU0wuQUdSLkVNUEwuTUEuWlMpLCBzaXplPTIsIGNvbG9yPWFncl9jb2xvcikgKw0KICANCiAgc2NhbGVfeV9jb250aW51b3VzKA0KICAgIA0KICAgICMgRmlyc3QgYXhpcw0KICAgIG5hbWUgPSAiRW1wbG95bWVudCBpbiBpbmR1c3RyeSwgbWFsZSAoJSBvZiBtYWxlIGVtcGxveW1lbnQpIiwNCiAgICANCiAgICAjIFNlY29uZCBheGlzDQogICAgc2VjLmF4aXMgPSBzZWNfYXhpcyh+LioxLCBuYW1lPSJFbXBsb3ltZW50IGluIGFncmljdWx0dXJlLCBtYWxlICglIG9mIG1hbGUgZW1wbG95bWVudCkiKQ0KICApICsNCg0KIyAgdGhlbWVfaXBzdW0oKSArDQogIHNjYWxlX3hfY29udGludW91cygNCiAgICBuYW1lID0gIllFQVIiDQogICkgKw0KDQogIHRoZW1lKA0KICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChjb2xvciA9IGluZF9jb2xvciwgc2l6ZT0xMyksDQogICAgYXhpcy50aXRsZS55LnJpZ2h0ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gYWdyX2NvbG9yLCBzaXplPTEzKQ0KICApICsNCg0KICBnZ3RpdGxlKCJFbXBsb3ltZW50IGluIGluZHVzdHJ5ICYgYWdyaWN1bHR1cmUsIG1hbGVzIG92ZXIgdGltZSIpICsNCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkpICNUaXRsZSB0byBiZSBhdCBjZW50ZXINCmBgYA0KICAxLiBQZXJjZW50YWdlIGluIG1hbGUgZW1wbG95bWVudCBpbiBpbmR1c3RyeSBoYXMgYmVlbiBpbmNyZWFzaW5nIGJ5IC4NCiAgMi4gUGVyY2VudGFnZSBpbiBtYWxlIGVtcGxveW1lbnQgaW4gYWdyaWN1bHR1cmUgaGFzIGJlZW4gZGVjcmVhc2luZyBieSAuDQoNCg0KYGBge3J9DQoNCmBgYA0KDQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KDQoNClJlZ3Jlc3Npb246DQoNCiNoZWxwKCJzY2FsZV94X2NvbnRpbnVvdXMiKQ0KDQpgYGB7cn0NCmdncGxvdChuZXBhbF9kZiwgYWVzKHggPSBHQy5UQVguR1NSVi5DTiwgeSA9IE5ZLkdEUC5NS1RQLktEKSkgKw0KICBnZW9tX3BvaW50KCkgKw0KZ2VvbV9zbW9vdGgoKSArIA0KIyBBZGQgYSByZWdyZXNzaW9uIGxpbmUNCnhsYWIoIlRheGVzIG9uIGdvb2RzIGFuZCBzZXJ2aWNlcyAoY3VycmVudCBMQ1UpIikgKw0KeWxhYigiR0RQIChjb25zdGFudCAyMDE1IFVTJCkiKSArDQpzY2FsZV94X2NvbnRpbnVvdXMoKSArDQpzY2FsZV95X2NvbnRpbnVvdXMoKSArDQpnZ3RpdGxlKCJSZWdyZXNzaW9uOiBHRFAgeCB0YXhlcyBvbiBnb29kcyAmIHNlcnZpY2VzIikNCmBgYA0KICAxLiBBcyB0YXhlcyBvbiBnb29kcyBhbmQgc2VydmljZXMgaW5jcmVhc2VzLCB0aGUgR0RQIGhhcyBiZWVuIGluY3JlYXNpbmcuIA0KICAyLiBUaGUgY29ycmVsYXRpb24gYmV0d2VlbiB0aGUgdHdvIGluZGljYXRvcnMgKCkgYXMgLCBzYXlzIHRoZSBzYW1lLg0KICANCg0KYGBge3J9DQojIENoZWNraW5nIEdEUCBncm93dGggb24gZXZlcnkgdGF4ICUgaW5jcmVhc2UNCiMgd2l0aCB0cmVuZCBsaW5lIChyZWdyZXNzaW9uIGxpbmUpDQoNCmdncGxvdChuZXBhbF9kZiwgYWVzKHggPSBHQy5UQVguR1NSVi5WQS5aUywgeSA9IE5ZLkdEUC5NS1RQLktEKSkgKw0KICBnZW9tX3BvaW50KCkgKw0KZ2VvbV9zbW9vdGgoKSArICMgQWRkIGEgcmVncmVzc2lvbiBsaW5lDQp4bGFiKCJUYXhlcyBvbiBnb29kcyBhbmQgc2VydmljZXMgKCUgdmFsdWUgYWRkZWQgb2YgaW5kdXN0cnkgYW5kIHNlcnZpY2VzKSIpICsNCnlsYWIoIkdEUCAoY29uc3RhbnQgMjAxNSBVUyQpIikgKw0Kc2NhbGVfeF9jb250aW51b3VzKCkgKw0Kc2NhbGVfeV9jb250aW51b3VzKCkgKw0KZ2d0aXRsZSgiUmVncmVzc2lvbjogR0RQIHggdGF4ZXMgb24gZ29vZHMgJiBzZXJ2aWNlcyIpDQpgYGANCiAgMS4gVGF4ZXMgb24gZ29vZHMgYW5kIHNlcnZpY2VzIGFib3ZlIDEwJSBzaG93cyBpbmNyZWFzZSBpbiBHRFAuDQogIDIuIFdoZW4gdGF4ZXMgb24gZ29vZHMgYW5kIHNlcnZpY2VzIGFyZSB3aXRoaW4gdGhlIHJhbmdlIDYuNSUgdG8gOC41JSwgdGhlIEdEUCBoYXMgYmVlbiBmbHVjdHVhdGluZy4NCiAgDQogIA0KYGBge3J9DQojIENoZWNrIGVtcGxveW1lbnQgaW4gaW5kdXN0cnkgb24gZXZlcnkgdGF4ICUgaW5jcmVhc2UNCiMgd2l0aCB0cmVuZCBsaW5lIChyZWdyZXNzaW9uIGxpbmUpDQoNCmdncGxvdChuZXBhbF9kZiwgYWVzKHggPSBTTC5JTkQuRU1QTC5aUywgeSA9IEdDLlRBWC5HU1JWLlZBLlpTKSkgKw0KICBnZW9tX3BvaW50KCkgKw0KZ2VvbV9zbW9vdGgoKSArICMgQWRkIGEgcmVncmVzc2lvbiBsaW5lDQp4bGFiKCJFbXBsb3ltZW50IGluIGluZHVzdHJ5ICglIG9mIHRvdGFsIGVtcGxveW1lbnQpIikgKw0KeWxhYigiVGF4ZXMgb24gZ29vZHMgYW5kIHNlcnZpY2VzICglIHZhbHVlIGFkZGVkIG9mIGluZHVzdHJ5IGFuZCBzZXJ2aWNlcykiKSArDQpzY2FsZV94X2NvbnRpbnVvdXMoKSArDQpzY2FsZV95X2NvbnRpbnVvdXMoKSArDQpnZ3RpdGxlKCJSZWdyZXNzaW9uOiBUYXggb24gZ29vZHMgJiBzZXJ2aWNlcyBYIEVtcGxveW1lbnQgaW4gaW5kdXN0cnkiKQ0KYGBgDQogIDEuIEluY3JlYXNlIGluIHRheGVzIG9uIGdvb2RzIGFuZCBzZXJ2aWNlcyBhYm92ZSA3JSBzaG93cyBpbmNyZWFzZSBpbiBwZXJjZW50IG9mIGVtcGxveW1lbnQgaW4gaW5kdXN0cnkuDQogIDIuIExpa2V3aXNlLCB0aGUgdGF4ZXMgYXJvdW5kIDcuNSUgc2hvd3MgcGVyY2VudCBvZiBlbXBsb3ltZW50IGluIGluZHVzdHJ5IGZyb20gMi41JSB0byAxMCUuDQogIA0KICANCmBgYHtyfQ0KIyBDaGVjayBlbXBsb3ltZW50IGluIGFncmljdWx0dXJlIG9uIGV2ZXJ5IHRheCAlIGluY3JlYXNlDQojIHdpdGggdHJlbmQgbGluZSAocmVncmVzc2lvbiBsaW5lKQ0KDQpnZ3Bsb3QobmVwYWxfZGYsIGFlcyh4ID0gR0MuVEFYLkdTUlYuVkEuWlMsIHkgPSBTTC5BR1IuRU1QTC5aUyApKSArDQogIGdlb21fcG9pbnQoKSArDQpnZW9tX3Ntb290aCgpICsgIyBBZGQgYSByZWdyZXNzaW9uIGxpbmUNCnhsYWIoIlRheGVzIG9uIGdvb2RzIGFuZCBzZXJ2aWNlcyAoJSB2YWx1ZSBhZGRlZCBvZiBpbmR1c3RyeSBhbmQgc2VydmljZXMpIikgKw0KeWxhYigiRW1wbG95bWVudCBpbiBhZ3JpY3VsdHVyZSAoJSBvZiB0b3RhbCBlbXBsb3ltZW50KSIpICsNCnNjYWxlX3hfY29udGludW91cygpICsNCnNjYWxlX3lfY29udGludW91cygpICsNCmdndGl0bGUoIlJlZ3Jlc3Npb246IFRheCBvbiBnb29kcyAmIHNlcnZpY2VzIFggRW1wbG95bWVudCBpbiBhZ3JpY3VsdHVyZSIpDQpgYGANCiAgMS4gRGVzcGl0ZSB0aGUgY29ycmVsYXRpb24gYmV0d2VlbiB0aGUgaW5kaWNhdG9ycyAoKSwgdGhlIGluY3JlYXNlIGluIHRheGVzIG9uIGdvb2RzIGFuZCBzZXJ2aWNlcyBzaG93cyBzbG93IGRlY3JlYXNlICAgICAgaW4gZW1wbG95bWVudCBpbiBhZ3JpY3VsdHVyZS4NCiAgDQogIA0KYGBge3J9DQojIENoZWNrIGVtcGxveW1lbnQgaW4gaW5kdXN0cnkgb24gZXZlcnkgY3VzdG9tcy9pbXBvcnQgZHV0aWVzICUgaW5jcmVhc2UNCiMgd2l0aCB0cmVuZCBsaW5lIChyZWdyZXNzaW9uIGxpbmUpDQoNCmdncGxvdChuZXBhbF9kZiwgYWVzKHggPSBHQy5UQVguSU1QVC5aUywgeSA9IFNMLklORC5FTVBMLlpTKSkgKw0KICBnZW9tX3BvaW50KCkgKw0KZ2VvbV9zbW9vdGgoKSArICMgQWRkIGEgcmVncmVzc2lvbiBsaW5lDQp4bGFiKCJDdXN0b21zIGFuZCBvdGhlciBpbXBvcnQgZHV0aWVzICglIG9mIHRheCByZXZlbnVlKSIpICsNCnlsYWIoIkVtcGxveW1lbnQgaW4gaW5kdXN0cnkgKCUgb2YgdG90YWwgZW1wbG95bWVudCkiKSArDQpzY2FsZV94X2NvbnRpbnVvdXMoKSArDQpzY2FsZV95X2NvbnRpbnVvdXMoKSArDQpnZ3RpdGxlKCJSZWdyZXNzaW9uOiBDdXN0b21zIEltcG9ydCBkdXRpZXMgWCBFbXBsb3ltZW50IGluIGluZHVzdHJ5IikNCmBgYA0KICAxLiBBcyBjdXN0b21zIGFuZCBpbXBvcnQgZHV0aWVzIGluY3JlYXNlcywgdGhlIGVtcGxveW1lbnQgaW4gaW5kdXN0cmlhbCBzZWN0b3IgZGVjcmVhc2VzLg0KICAyLiBJdCBjYW4gYmUgY29uY2x1ZGVkIHRoYXQgYXMgY3VzdG9tcyBhbmQgaW1wb3J0IGR1dGllcyBpcyBhYm92ZSAyNSUsIHdlIGNhbiBzZWUgc3RlZXAgZGVjbGluZSBpbiBlbXBsb3ltZW50IGluICAgICAgICAgICBpbmR1c3RyeS4NCg0KDQpgYGB7cn0NCiMgQ2hlY2sgZW1wbG95bWVudCBpbiBhZ3JpY3VsdHVyZSBvbiBldmVyeSBjdXN0b21zL2ltcG9ydCBkdXRpZXMgJSBpbmNyZWFzZQ0KIyB3aXRoIHRyZW5kIGxpbmUgKHJlZ3Jlc3Npb24gbGluZSkNCg0KZ2dwbG90KG5lcGFsX2RmLCBhZXMoeCA9IEdDLlRBWC5JTVBULlpTLCB5ID0gU0wuQUdSLkVNUEwuWlMpKSArDQogIGdlb21fcG9pbnQoKSArDQpnZW9tX3Ntb290aCgpICsgIyBBZGQgYSByZWdyZXNzaW9uIGxpbmUNCnhsYWIoIkN1c3RvbXMgYW5kIG90aGVyIGltcG9ydCBkdXRpZXMgKCUgb2YgdGF4IHJldmVudWUpIikgKw0KeWxhYigiRW1wbG95bWVudCBpbiBhZ3JpY3VsdHVyZSAoJSBvZiB0b3RhbCBlbXBsb3ltZW50KSIpICsNCnNjYWxlX3hfY29udGludW91cygpICsNCnNjYWxlX3lfY29udGludW91cygpICsNCmdndGl0bGUoIlJlZ3Jlc3Npb246IEN1c3RvbXMgSW1wb3J0IGR1dGllcyBYIEVtcGxveW1lbnQgaW4gYWdyaWN1bHR1cmUiKQ0KYGBgDQogIDEuIFRob3VnaCB0aGUgY29ycmVsYXRpb24gYmV0d2VlbiB0aGUgdHdvIGluZGljYXRvciAoIGFuZCApIGlzICwgdGhlIGluY3JlYXNlIGluIGN1c3RvbXMgYW5kIGltcG9ydCBkdXRpZXMgaGFzIHNtYWxsICAgICAgIGNoYW5nZSBvbiB0aGUgZW1wbG95bWVudCBpbiBhZ3JpY3VsdHVyZS4NCg0KDQpgYGB7cn0NCiMgQ2hlY2sgZW1wbG95bWVudCBpbiBpbmR1c3RyeSBvbiBldmVyeSBleHBvcnQgdGF4ZXMgJSBpbmNyZWFzZQ0KIyB3aXRoIHRyZW5kIGxpbmUgKHJlZ3Jlc3Npb24gbGluZSkNCg0KZ2dwbG90KG5lcGFsX2RmLCBhZXMoeCA9IEdDLlRBWC5FWFBULlpTICwgeSA9IFNMLklORC5FTVBMLlpTICkpICsNCiAgZ2VvbV9wb2ludCgpICsNCmdlb21fc21vb3RoKCkgKyAjIEFkZCBhIHJlZ3Jlc3Npb24gbGluZQ0KeGxhYigiVGF4ZXMgb24gZXhwb3J0cyAoJSBvZiB0YXggcmV2ZW51ZSkiKSArDQp5bGFiKCJFbXBsb3ltZW50IGluIGluZHVzdHJ5ICglIG9mIHRvdGFsIGVtcGxveW1lbnQpIikgKw0Kc2NhbGVfeF9jb250aW51b3VzKCkgKw0Kc2NhbGVfeV9jb250aW51b3VzKCkgKw0KZ2d0aXRsZSgiUmVncmVzc2lvbjogRXhwb3J0cyB0YXhlcyB2cyBFbXBsb3ltZW50IGluIEluZHVzdHJ5IikNCmBgYA0KICAxLiBBcyB0YXhlcyBvbiBleHBvcnRzIGluY3JlYXNlcywgdGhlIGVtcGxveW1lbnQgaW4gaW5kdXN0cnkgcmVtYWlucyB1bmNoYW5nZWQoYnV0IHNsaWdodGx5IGRlY3JlYXNpbmcpLg0KDQoNCmBgYHtyfQ0KIyBDaGVjayBlbXBsb3ltZW50IGluIGFncmljdWx0dXJlIG9uIGV2ZXJ5IGV4cG9ydCB0YXhlcyAlIGluY3JlYXNlDQojIHdpdGggdHJlbmQgbGluZSAocmVncmVzc2lvbiBsaW5lKQ0KDQpnZ3Bsb3QobmVwYWxfZGYsIGFlcyh4ID0gR0MuVEFYLkVYUFQuWlMsIHkgPSBTTC5BR1IuRU1QTC5aUykpICsNCiAgZ2VvbV9wb2ludCgpICsNCmdlb21fc21vb3RoKCkgKyAjIEFkZCBhIHJlZ3Jlc3Npb24gbGluZQ0KeGxhYigiVGF4ZXMgb24gZXhwb3J0cyAoJSBvZiB0YXggcmV2ZW51ZSkiKSArDQp5bGFiKCJFbXBsb3ltZW50IGluIGFncmljdWx0dXJlICglIG9mIHRvdGFsIGVtcGxveW1lbnQpIikgKw0Kc2NhbGVfeF9jb250aW51b3VzKCkgKw0Kc2NhbGVfeV9jb250aW51b3VzKCkgKw0KZ2d0aXRsZSgiUmVncmVzc2lvbjogRXhwb3J0cyB2cyBFbXBsb3ltZW50IGluIEFncmljdWx0dXJlIikNCmBgYA0KICAxLiBBcyB0YXhlcyBvbiBleHBvcnRzIGluY3JlYXNlcywgdGhlIGVtcGxveW1lbnQgaW4gYWdyaWN1bHR1cmUgcmVtYWlucyB1bmNoYW5nZWQoYnV0IHNsaWdodGx5IGluY3JlYXNpbmcpLg0KDQoNCmBgYHtyfQ0KDQpgYGANCg0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCg0KDQpCYXIgUGxvdHM6DQoNCmBgYHtyfQ0KIyBCYXIgcGxvdCBmb3IgR0RQIHZzIGVtcGxveW1lbnQgaW4gaW5kdXN0cnkNCg0KZ2dwbG90KG5lcGFsX2RmLCBhZXMoeCA9IG5lcGFsX2RmJFNMLklORC5FTVBMLlpTLCB5ID0gbmVwYWxfZGYkTlkuR0RQLk1LVFAuS0QsIGZpbGwgPSBuZXBhbF9kZiRTTC5JTkQuRU1QTC5aUykpICsNCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHBvc2l0aW9uID0gImRvZGdlIiwgd2lkdGggPSAwLjA4KSArDQogICN0aGVtZV9idygpICsNCiAgeGxhYigiRW1wbG95bWVudCBpbiBpbmR1c3RyeSAoJSBvZiB0b3RhbCBlbXBsb3ltZW50KSIpICsNCiAgeWxhYigiR0RQIChjb25zdGFudCAyMDE1IFVTJCkiKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCkpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSkgKw0KICBnZ3RpdGxlKCJCYXIgcGxvdDogR0RQIHZzIEVtcGxveW1lbnQgaW4gaW5kdXN0cnkiKQ0KYGBgDQogIDEuIEdEUCBpcyBoaWdoZXN0KGFyb3VuZCAkMzAgYmlsbGlvbikgd2hlbiBlbXBsb3ltZW50IGluIGluZHVzdHJ5KCUgb2YgdG90YWwgZW1wbG95bWVudCkgaXMgMTUlLg0KICAyLiBHRFAgaXMgbG93ZXN0KGJlbG93ICQxMCBiaWxsaW9uKSB3aGVuIGVtcGxveW1lbnQgaW4gaW5kdXN0cnkoJSBvZiB0b3RhbCBlbXBsb3ltZW50KSBpcyAyLjclLg0KDQoNCmBgYHtyfQ0KIyBCYXIgcGxvdCBmb3IgR0RQIHZzIHRheGVzIG9uIGdvb2QgYW5kIHNlcnZpY2VzDQoNCmdncGxvdChuZXBhbF9kZiwgYWVzKHggPSBuZXBhbF9kZiRHQy5UQVguR1NSVi5WQS5aUywgeSA9IG5lcGFsX2RmJE5ZLkdEUC5NS1RQLktELCBmaWxsID0gbmVwYWxfZGYkR0MuVEFYLkdTUlYuVkEuWlMpKSArDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9ICJkb2RnZSIsIHdpZHRoID0gMC4wOCkgKw0KICAjdGhlbWVfYncoKSArDQogIHhsYWIoIlRheGVzIG9uIGdvb2RzIGFuZCBzZXJ2aWNlcyglKSIpICsNCiAgeWxhYigiR0RQIChjb25zdGFudCAyMDE1IFVTJCkiKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCkpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSkgKw0KICBnZ3RpdGxlKCJCYXIgcGxvdDogR0RQIHZzIFRheGVzIG9uIGdvb2RzICYgc2VydmljZXMoJSkiKQ0KDQpgYGANCiAgMS4gR0RQIGlzIGhpZ2hlc3QoYXJvdW5kICQzMCBiaWxsaW9uKSB3aGVuIGVtcGxveW1lbnQgaW4gdGF4ZXMgb24gZ29vZHMgYW5kIHNldmljZXMgaXMgMTAuNiUuDQogIDIuIEdEUCBpcyBsb3dlc3QoYmVsb3cgJDEwIGJpbGxpb24pIHdoZW4gZW1wbG95bWVudCBpbiBpbmR1c3RyeSglIG9mIHRvdGFsIGVtcGxveW1lbnQpIGlzIDclLg0KDQoNCmBgYHtyfQ0KDQpgYGANCg0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCg0KDQpDbHVzdGVyIEFuYWx5c2lzOg0KDQpgYGB7cn0NCiMgU2NhdHRlcnBsb3QgZm9yIFRheGVzIG9uIGdvb2RzIGFuZCBzZXJ2aWNlcyBhbmQgR0RQDQoNCmxpYnJhcnkoc2NhdHRlcnBsb3QzZCkNCnNjYXR0ZXJwbG90M2QobmVwYWxfZGYkR0MuVEFYLkdTUlYuQ04sIG5lcGFsX2RmJE5ZLkdEUC5NS1RQLktELCBuZXBhbF9kZiRTTC5JTkQuRU1QTC5aUywNCiAgICAgICAgICAgICAgeGxhYiA9ICJUYXgiLCB5bGFiID0gIkdEUCIsIHpsYWIgPSAiRW1wbG95bWVudCIsDQogICAgICAgICAgICAgIHR5cGUgPSAiaCIsIG1haW4gPSAiM0QgU2NhdHRlcnBsb3QiKQ0KYGBgDQoNCmBgYHtyfQ0KI2xpYnJhcnkocmdsKQ0KI3Bsb3QzZChuZXBhbF9kZiRHQy5UQVguR1NSVi5DTiwgbmVwYWxfZGYkTlkuR0RQLk1LVFAuS0QsIG5lcGFsX2RmJFNMLklORC5FTVBMLlpTKQ0KYGBgDQoNCmBgYHtyfQ0KDQpgYGANCg0KQWRkIGEgbmV3IGNodW5rIGJ5IGNsaWNraW5nIHRoZSAqSW5zZXJ0IENodW5rKiBidXR0b24gb24gdGhlIHRvb2xiYXIgb3IgYnkgcHJlc3NpbmcgKkN0cmwrQWx0K0kqLg0KDQpXaGVuIHlvdSBzYXZlIHRoZSBub3RlYm9vaywgYW4gSFRNTCBmaWxlIGNvbnRhaW5pbmcgdGhlIGNvZGUgYW5kIG91dHB1dCB3aWxsIGJlIHNhdmVkIGFsb25nc2lkZSBpdCAoY2xpY2sgdGhlICpQcmV2aWV3KiBidXR0b24gb3IgcHJlc3MgKkN0cmwrU2hpZnQrSyogdG8gcHJldmlldyB0aGUgSFRNTCBmaWxlKS4NCg0KVGhlIHByZXZpZXcgc2hvd3MgeW91IGEgcmVuZGVyZWQgSFRNTCBjb3B5IG9mIHRoZSBjb250ZW50cyBvZiB0aGUgZWRpdG9yLiBDb25zZXF1ZW50bHksIHVubGlrZSAqS25pdCosICpQcmV2aWV3KiBkb2VzIG5vdCBydW4gYW55IFIgY29kZSBjaHVua3MuIEluc3RlYWQsIHRoZSBvdXRwdXQgb2YgdGhlIGNodW5rIHdoZW4gaXQgd2FzIGxhc3QgcnVuIGluIHRoZSBlZGl0b3IgaXMgZGlzcGxheWVkLg0KDQoNClRoaXMgaXMgYW4gW1IgTWFya2Rvd25dKGh0dHA6Ly9ybWFya2Rvd24ucnN0dWRpby5jb20pIE5vdGVib29rLiBXaGVuIHlvdSBleGVjdXRlIGNvZGUgd2l0aGluIHRoZSBub3RlYm9vaywgdGhlIHJlc3VsdHMgYXBwZWFyIGJlbmVhdGggdGhlIGNvZGUuIA0KDQpUcnkgZXhlY3V0aW5nIHRoaXMgY2h1bmsgYnkgY2xpY2tpbmcgdGhlICpSdW4qIGJ1dHRvbiB3aXRoaW4gdGhlIGNodW5rIG9yIGJ5IHBsYWNpbmcgeW91ciBjdXJzb3IgaW5zaWRlIGl0IGFuZCBwcmVzc2luZyAqQ3RybCtTaGlmdCtFbnRlciouIA0K